﻿/**
 * \file CPoolAlloc.h
 * \reversion 0.1
 * \brief 基于内存池的分配器
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __CPOOL__ALLOC__H
#define __CPOOL__ALLOC__H

#ifdef _POOL_ALLOC_INFO
#	include <iostream>
#endif

#include "CStaticMemPool.h"
#include "CMemory.h"

/// 基于内存池的空间分配器
template <typename _Ty>
class CPoolAlloc
{
public:
	typedef typename _Ty value_type;
	typedef value_type* pointer;
	typedef value_type& reference;
	typedef const value_type* const_pointer;
	typedef const value_type& const_reference;

	typedef size_t size_type;
	typedef ptrdiff_t difference_type;

	template<class _Other>
	struct rebind
	{
		typedef CPoolAlloc<_Other> other;
	};

	/// get address
	pointer address(reference _Val) const
	{
		return (&_Val);
	}

	/// get const address
	const_pointer address(const_reference _Val) const
	{
		return (&_Val);
	}

	/// construct
	CPoolAlloc() throw()
	{}

	/// destruct
	~CPoolAlloc() throw()
	{}

	/// copy construct
	CPoolAlloc(const CPoolAlloc<_Ty>&) throw()
	{}

	/// copy construct
	template <class _Other>
	CPoolAlloc(const CPoolAlloc<_Other>&) throw()
	{}

	/// operator =
	template <class _Other>
	CPoolAlloc<value_type>& operator=(const CPoolAlloc<_Other>&) throw ()
	{
		return (*this);
	}

	/// deallocate memory space
	void deallocate(pointer _Ptr, size_type _Count)
	{
		if(!::s_Deallocate<value_type>(_Ptr, _Count))
		{
#ifdef _POOL_ALLOC_INFO
			std::cout << "【CPoolAlloc】deallocate error!" << std::endl;
#endif
		}
	}

	/// allocate memory space
	pointer allocate(size_type _Count)
	{
		return (pointer)::s_Allocate<value_type>(_Count);
	}

	/// allocate memory space
	pointer allocate(size_type _Count, const_pointer hint)
	{
		return this->allocate(_Count);
	}

	/// call construct function
	void construct(pointer _Ptr, const_reference _Val)
	{
		::s_Construct<value_type>(_Ptr, _Val);
	}

	/// call destruct function
	void destroy(pointer _Ptr)
	{
		::s_Destroy<value_type>(_Ptr);
	}

	/// max count of object
	size_type max_size() const throw()
	{
		size_type _Count = (size_type)(-1) / sizeof (value_type);
		return (0 < _Count ? _Count : 1);
	}
};

/// operator ==
template<class _Ty, class _Other>
inline bool operator==(const CPoolAlloc<_Ty>&, const CPoolAlloc<_Other>&) throw()
{
	return true;
}

/// operator !=
template<class _Ty, class _Other>
inline bool operator!=(const CPoolAlloc<_Ty>&, const CPoolAlloc<_Other>&) throw()
{
	return false;
}

/// 特化版本allocator<void>
template<>
class CPoolAlloc<void>
{
public:
	typedef void _Ty;
	typedef _Ty* pointer;
	typedef const _Ty* const_pointer;
	typedef _Ty value_type;

	template<class _Other>
	struct rebind
	{/// convert an allocator<void> to an allocator <_Other>
		typedef CPoolAlloc<_Other> other;
	};

	/// construct
	CPoolAlloc() throw()
	{}

	/// destruct
	~CPoolAlloc() throw()
	{}

	/// copy construct
	CPoolAlloc(const CPoolAlloc<_Ty>&) throw()
	{}

	/// copy construct
	template<class _Other>
	CPoolAlloc(const CPoolAlloc<_Other>&) throw()
	{}

	/// assign
	template<class _Other>
	CPoolAlloc<_Ty>& operator=(const CPoolAlloc<_Other>&)
	{
		return (*this);
	}
};

#endif	/// __CPOOL__ALLOC__H
